#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "dirlist.h"

int32_t						DIRLIST_CopyFile		(const char* aSource, const char* aDest, void (*aProgress)(off_t aNow, off_t aTotal))
{
	char* copybuffer = 0;
	off_t currentsize = 0;
	struct stat statbuffer;
	FILE* source;
	FILE* target;

	/* If we can't stat source, give up */
	if(stat(aSource, &statbuffer) || !statbuffer.st_size & S_IFREG)
	{
		return 1;
	}

	source = fopen(aSource, "rb");
	target = fopen(aDest, "wb");

	if(source && target)
	{
		copybuffer = malloc(64 * 1024);

		while(copybuffer && !feof(source))
		{
			size_t count = fread(copybuffer, 1, 64 * 1024, source);
			fwrite(copybuffer, 1, 64 * 1024, target);

			currentsize += count;

			if(aProgress)
			{
				aProgress(currentsize, statbuffer.st_size);
			}
		}

		free(copybuffer);
	}

	if(source)
	{
		fclose(source);
	}

	if(target)
	{
		fclose(target);
	}

	return 0;
}

void						DIRLIST_Delete			(struct DirectoryList* aList)
{
	struct DirectoryList* Next = 0;

	if(aList)
	{
		Next = aList->Next;
		free(aList);
	}
	else
	{
		return;
	}

	DIRLIST_Delete(Next);
}

struct DirectoryList*		DIRLIST_FindFile		(struct DirectoryList* aList, const char* aFile)
{
	struct DirectoryList* current = aList;

	while(current)
	{
		if((current->Item.d_type & DT_REG) && (strcasecmp(current->Item.d_name, aFile) == 0))
		{
			return current;
		}

		current = current->Next;
	}

	return 0;
}

struct DirectoryList*		DIRLIST_Create			(const char* aPath)
{
	DIR* dirhandle;
	struct dirent* item;

	if((dirhandle = opendir(aPath)))
	{
		struct DirectoryList* output = malloc(sizeof(struct DirectoryList));
		struct DirectoryList* current = output;
		int itemzero = 1;

		output->Next = 0;

		while((item = readdir(dirhandle)))
		{
			if(strcmp(item->d_name, ".") == 0 || strcmp(item->d_name, "..") == 0)
			{
				continue;
			}

			if(!itemzero)
			{
				current->Next = malloc(sizeof(struct DirectoryList));
				current = current->Next;
				current->Next = 0;
			}
			itemzero = 0;

			memcpy(&current->Item, item, sizeof(struct dirent));
			snprintf(current->FullPath, MAX_PATH, "%s/%s", aPath, item->d_name);
		}

		closedir(dirhandle);
		return output;
	}

	return 0;
};

